#include "C3DMotionImporterDialog.h"
#include "ui_C3DMotionImporterDialog.h"

#include <MMM/Motion/Plugin/MoCapMarkerPlugin/MoCapMarkerSensor.h>

#include <QCheckBox>
#include <QMessageBox>
#include <set>

C3DMotionImporterDialog::C3DMotionImporterDialog(const std::string &motionFilePath, QWidget* parent) :
    QDialog(parent),
    ui(new Ui::C3DMotionImporterDialog),
    converter(new MMM::C3DConverter(motionFilePath))
{
    ui->setupUi(this);
    markerPrefixes = converter->getPrefixMarkerData()->getPrefixes();

    motionList = new MotionListWidget(markerPrefixes, "Marker prefix: ");

    ui->motionListLayout->addWidget(motionList);

    connect(ui->importMotionButton, SIGNAL(clicked()), this, SLOT(importMotion()));
    connect(ui->cancelButton, SIGNAL(clicked()), this, SLOT(close()));
}

C3DMotionImporterDialog::~C3DMotionImporterDialog() {
    delete ui;
}

std::vector<std::tuple<std::string, std::string> > C3DMotionImporterDialog::createNamePrefixMap() {
    std::vector<MMM::MotionListConfigurationPtr> configurations = motionList->getConfigurations();
    std::sort(configurations.begin(), configurations.end(), MMM::SortByNewIndexFunctor());

    // TODO! wrong order, because map is sorted. fuck!
    std::vector<std::tuple<std::string, std::string> > motionNameToMarkerPrefix;
    for (auto configuration : configurations) {
        if (!configuration->isIgnoreMotion()) {
            std::string markerPrefix = markerPrefixes.at(configuration->getIndex());
            std::string motionName = configuration->getMotionName();
            if (motionName.empty())
            {
                motionName = "Motion_" + std::to_string(configuration->getIndex());
            }
            {
                for (const auto &mapping : motionNameToMarkerPrefix) {
                    if (std::get<0>(mapping) == motionName)
                        throw MMM::Exception::MMMException("The motion name '" + motionName + "' for the marker prefix '" + markerPrefix + "' is already contained!");
                }
                motionNameToMarkerPrefix.push_back(std::make_tuple(motionName, markerPrefix));
            }
        }
    }
    if (motionNameToMarkerPrefix.size() == 0) throw MMM::Exception::MMMException("Cannot import motion. No mapping specified!");
    return motionNameToMarkerPrefix;
}

void C3DMotionImporterDialog::importMotion() {
    try {
        motions = converter->convertMotions(createNamePrefixMap());
        this->close();
    } catch (MMM::Exception::MMMException& e) {
        QMessageBox* msgBox = new QMessageBox(this);
        msgBox->setText(QString::fromStdString(e.what()));
        msgBox->exec();
    }
}

MMM::MotionList C3DMotionImporterDialog::getMotions() {
    exec();
    return motions;
}
